/*
 * Copyright 2018 JessYan
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.eduhzy.ttw.commonres.utils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.text.Html;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.blankj.utilcode.util.ObjectUtils;
import com.eduhzy.ttw.commonres.R;
import com.eduhzy.ttw.commonsdk.entity.CommonData;
import com.eduhzy.ttw.commonsdk.entity.UploadData;
import com.eduhzy.ttw.commonsdk.http.CommonApi;
import com.jess.arms.integration.IRepositoryManager;
import com.jess.arms.mvp.IView;
import com.jess.arms.utils.ArmsUtils;
import com.jess.arms.utils.RxLifecycleUtils;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.zhy.autolayout.AutoLinearLayout;

import java.io.File;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.handler.RetryWithDelay;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

import static com.eduhzy.ttw.commonsdk.core.Constants.uploadAppId;
import static com.eduhzy.ttw.commonsdk.core.Constants.uploadAppKey;

/**
 * ================================================
 * Created by JessYan on 30/03/2018 17:16
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * ================================================
 */
public class RxUtil {
    private RxUtil() {
        throw new IllegalStateException("you can't instantiate me!");
    }

    /**
     * 执行io线程, 取消注册在io, 回掉主线程
     *
     * @param <T>
     * @return
     */
    public static <T> ObservableTransformer<T, T> io_main() {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                return upstream
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread());
            }
        };
    }

    /**
     * 重试
     *
     * @param <T>
     * @return 重试次数
     */
    public static <T> ObservableTransformer<T, T> retry2() {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                return upstream.retryWhen(new RetryWithDelay(2, 2));
            }
        };
    }

    /**
     * 都在io线程
     *
     * @param <T>
     * @return
     */
    public static <T> ObservableTransformer<T, T> all_io() {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                return upstream
                        .subscribeOn(Schedulers.io())
                        .observeOn(Schedulers.io());
            }
        };
    }

    public static <T> ObservableTransformer<T, T> applySchedulers(final IView view) {
        return new ObservableTransformer<T, T>() {
            @Override
            public Observable<T> apply(Observable<T> observable) {
                return observable.subscribeOn(Schedulers.io())
                        .doOnSubscribe(new Consumer<Disposable>() {
                            @Override
                            public void accept(@NonNull Disposable disposable) throws Exception {
                                view.showLoading();//显示进度条
                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doFinally(new Action() {
                            @Override
                            public void run() {
                                view.hideLoading();//隐藏进度条
                            }
                        }).compose(RxLifecycleUtils.bindToLifecycle(view));
            }
        };
    }

    public static void showTipDialog(Context context, int type, String tip) {
        Toast.makeText(context, tip, Toast.LENGTH_LONG).show();
//        showTipDialog(context, type, tip, 1500);
    }

    public static void showTipDialog(Context context, int type, String tip, long delay) {
        Toast.makeText(context, tip, Toast.LENGTH_LONG).show();
        /*QMUITipDialog qmuiTipDialog = new QMUITipDialog.Builder(context)
                .setIconType(type)
                .setTipWord(tip)
                .create(false);
        qmuiTipDialog.setCanceledOnTouchOutside(type != QMUITipDialog.Builder.ICON_TYPE_LOADING);
        qmuiTipDialog.show();
        try {
            new Handler().postDelayed(qmuiTipDialog::dismiss, delay);
        } catch (Throwable e) {
            qmuiTipDialog = null;
            e.printStackTrace();
        }*/
    }

    public static QMUITipDialog showLoading(Context context, String message) {
        return new QMUITipDialog
                .Builder(context)
                .setTipWord(message)
                .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
                .create(false);
    }

    public static void delayToDo(long delayTime, final OnSimpleListener onSimpleListener) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //execute the task
                onSimpleListener.doSomething();
            }
        }, delayTime);
    }

    //上传图片
    public static Observable<CommonData<UploadData>> uploadImage(String filePath, IRepositoryManager retrofit) {
        return upload(filePath, MediaType.parse("image/png"), retrofit);
    }

    public static Observable<CommonData<UploadData>> uploadImage(String filePath, String url, IRepositoryManager retrofit) {
        return upload(filePath, MediaType.parse("image/png"), url, retrofit);
    }

    public static Observable<CommonData<UploadData>> uploadVideo(String filePath, IRepositoryManager retrofit) {
        return upload(filePath, MediaType.parse("video/*"), retrofit);
    }

    public static Observable<CommonData<UploadData>> uploadAudio(String filePath, IRepositoryManager retrofit) {
        return upload(filePath, MediaType.parse("audio/*"), retrofit);
    }

    //上传
    public static Observable<CommonData<UploadData>> upload(String filePath, MediaType mediaType, IRepositoryManager retrofit) {
        MultipartBody.Builder part = new MultipartBody.Builder();
        MultipartBody.Part pquestionId = MultipartBody.Part.createFormData("appid", uploadAppId);
        MultipartBody.Part pAutho = MultipartBody.Part.createFormData("appkey", uploadAppKey);
        part.addPart(pquestionId);
        part.addPart(pAutho);
        File mFilePath = new File(filePath);
        RequestBody requestBody =
                RequestBody.create(mediaType, mFilePath);
        part.addFormDataPart("file", mFilePath.getName(), requestBody);
        return retrofit.obtainRetrofitService(CommonApi.class).upload(part.build());
    }

    /**
     * 附带上传url
     *
     * @param filePath
     * @param mediaType
     * @param url
     * @param retrofit
     * @return
     */
    public static Observable<CommonData<UploadData>> upload(String filePath, MediaType mediaType, String url, IRepositoryManager retrofit) {
        MultipartBody.Builder part = new MultipartBody.Builder();
        MultipartBody.Part pquestionId = MultipartBody.Part.createFormData("appid", uploadAppId);
        MultipartBody.Part pAutho = MultipartBody.Part.createFormData("appkey", uploadAppKey);
        part.addPart(pquestionId);
        part.addPart(pAutho);
        File mFilePath = new File(filePath);
        RequestBody requestBody =
                RequestBody.create(mediaType, mFilePath);
        part.addFormDataPart("file", mFilePath.getName(), requestBody);
        return retrofit.obtainRetrofitService(CommonApi.class).upload(url, part.build());
    }

    public static void showConfirmDialog(Context context, String message, QMUIDialogAction.ActionListener listener) {
        showConfirmDialog(context, "标题", message, listener);
    }

    public static void showConfirmDialog(Context context, String title, String message, QMUIDialogAction.ActionListener listener) {
        new QMUIDialog.MessageDialogBuilder(context)
                .setTitle(title)
                .setMessage(message)
                .setCanceledOnTouchOutside(false)
                .setCancelable(false)
                .addAction("取消", (QMUIDialog dialog, int index) -> dialog.dismiss())
                .addAction(0, "确定", QMUIDialogAction.ACTION_PROP_POSITIVE,
                        (QMUIDialog dialog, int index) -> listener.onClick(dialog, index))
                .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show();
    }
    public static void showDeleteDialog(Context context, String title,String message, QMUIDialogAction.ActionListener listener) {

        new QMUIDialog.MessageDialogBuilder(context)
                .setTitle(title)
                .setMessage(message)
                .addAction("取消", new QMUIDialogAction.ActionListener() {
                    @Override
                    public void onClick(QMUIDialog dialog, int index) {
                        listener.onClick(dialog, index);
                    }
                })
                .addAction(0, "删除", QMUIDialogAction.ACTION_PROP_NEGATIVE, new QMUIDialogAction.ActionListener() {
                    @Override
                    public void onClick(QMUIDialog dialog, int index) {
                        listener.onClick(dialog, index);
                    }
                })
                .create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show();
    }

    public static void showDeleteDialog(Context context, String message, QMUIDialogAction.ActionListener listener) {
        showDeleteDialog(context,"标题",message,listener);
    }

    public static void showDeleteDialog(Context context, QMUIDialogAction.ActionListener listener) {
        showDeleteDialog(context, "确定要删除吗？", listener);
    }

    public static Context mNowContext;

    public static String getClassCode(String baseNo) {
        return "class_" + baseNo;
    }

    public static String getUserCode(String baseNo) {
        return "user_" + baseNo;
    }


    public static int getAutoHeight(Context context, int height) {
        ApplicationInfo applicationInfo;
        PackageManager packageManager = context.getPackageManager();
        try {
            applicationInfo = packageManager.getApplicationInfo(context
                    .getPackageName(), PackageManager.GET_META_DATA);
            if (applicationInfo == null || applicationInfo.metaData == null
                    || !applicationInfo.metaData.containsKey("design_width")
                    || !applicationInfo.metaData.containsKey("design_height")) {
                return height;
            }
            height = (int) (ArmsUtils.getScreenHeidth(context) * height / ((float) applicationInfo.metaData.getInt("design_height")));
        } catch (PackageManager.NameNotFoundException e) {
        }
        return height;
    }

    public static boolean showEditTip(IView view, EditText edit, String message) {
        if (ObjectUtils.isEmpty(edit.getText().toString())) {
            view.showMessage(message);
            return true;
        }
        return false;
    }


    public interface OnSimpleListener {
        void doSomething();
    }


    public static View getEmptyView(Context activity, ErrorCode type) {
        return getEmptyView(activity, R.layout.public_empty_layout, type);
    }

    public static View getEmptyView(Context activity, int res, ErrorCode type) {
        AutoLinearLayout view = (AutoLinearLayout) View.inflate(activity, res, null);
        ImageView iv = (ImageView) view.getChildAt(0);
        switch (type) {
            case load_error:
                iv.setBackgroundResource(R.drawable.no_interface);
                break;
            case no_data:
                iv.setBackgroundResource(R.drawable.no_data);
                break;
            case no_network:
                iv.setBackgroundResource(R.drawable.no_network);
                break;
        }
        return view;
    }

    public enum ErrorCode {
        no_data,
        no_network,
        load_error

    }

    public static int getAutoWidth(Context context, int width) {
        ApplicationInfo applicationInfo;
        PackageManager packageManager = context.getPackageManager();
        try {
            applicationInfo = packageManager.getApplicationInfo(context
                    .getPackageName(), PackageManager.GET_META_DATA);
            if (applicationInfo == null || applicationInfo.metaData == null
                    || !applicationInfo.metaData.containsKey("design_width")
                    || !applicationInfo.metaData.containsKey("design_height")) {
                return width;
            }
            int design_width = applicationInfo.metaData.getInt("design_width");
            width = (int) (ArmsUtils.getScreenWidth(context) * width / ((float) design_width));
        } catch (PackageManager.NameNotFoundException e) {
        }
        return width;


    }

    public static String fromHtml(String content) {
        content = parseContent(content);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            return Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY).toString();
        } else {
            return Html.fromHtml(content).toString();
        }
    }

    public static String parseContent(String content) {
        if (ObjectUtils.isNotEmpty(content)) {
            String content2 = content.replaceAll("\n", "<br>");
            return content2;
        }
        return null;
    }

}
